package com.cn.common.imp;

import java.io.Serializable;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.cn.common.IBaseDao;

import utils.GenericsUtils;
import utils.PageEntity;
import utils.PagingResult;
@Repository("baseDao")
public class BaseDao<T, PK, Key, Val extends Serializable> extends SqlSessionDaoSupport 
						implements IBaseDao<T, PK, Key, Val> {
	//MapperXml文件中的namespace
	Logger log = LoggerFactory.getLogger(BaseDao.class);
	private String Xmlnamespace;
	
	public String getXmlnamespace() {
		return Xmlnamespace;
	}
	public void setXmlnamespace(String xmlnamespace) {
		Xmlnamespace = xmlnamespace;
	}
	// sqlmap.xml定义文件中对应的sqlid  
    public static final String SQLID_INSERT = "insert";  
    public static final String SQLID_INSERT_BATCH = "insertList";  
    public static final String SQLID_UPDATE = "update";  
    public static final String SQLID_UPDATE_PARAM = "updateList";  
    public static final String SQLID_DELETE = "delete";  
    public static final String SQLID_DELETE_PARAM = "deleteList";  
    public static final String SQLID_TRUNCATE = "truncate";  
    public static final String SQLID_SELECT = "select";  
    public static final String SQLID_SELECT_PK = "selectPk";  
    public static final String SQLID_SELECT_PARAM = "selectParam"; 
    public static final String SQLID_SELECT_ONE = "selectOne";
    public static final String SQLID_SELECT_FK = "selectFk";  
    public static final String SQLID_COUNT = "count";  
    public static final String SQLID_COUNT_PARAM = "countParam";
    //实例sqlsession
    @Autowired  
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {  
        super.setSqlSessionFactory(sqlSessionFactory);  
    } 
    public int insert(T entity) {
    	int rows=0;
    	try{
    		rows = getSqlSession().insert(Xmlnamespace + "." + SQLID.SQLID_INSERT, entity);
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		return rows;
	}
	public T select(PK primaryKey) {
		try{
			return getSqlSession().selectOne(Xmlnamespace+"."+SQLID_SELECT, primaryKey);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	public int update(PK primaryKey) {
		int rows=0;
		try{
			rows = getSqlSession().update(Xmlnamespace+"."+SQLID_UPDATE, primaryKey);
		}catch(Exception e){
			e.printStackTrace();
		}
		return rows;
	}
	public int delete(PK primaryKey) {
		int rows = 0;
		try{
			rows = getSqlSession().delete(Xmlnamespace+"."+SQLID_DELETE, primaryKey);
		}catch(Exception e){
			e.printStackTrace();
		}
		return rows;
	}
	public int insertList(List<T> list) {
		int rows = 0;
		try{
			rows = getSqlSession().insert(Xmlnamespace+"."+SQLID_INSERT_BATCH, list);
		}catch(Exception e){
			e.printStackTrace();
		}
		return rows;
	}
	public int updateList(List<T> list) {
		int rows = 0;
		try{
			rows =getSqlSession().update(Xmlnamespace+"."+SQLID_UPDATE_PARAM, list);
		}catch(Exception e){
			e.printStackTrace();
		}
		return rows;
	}
	public int deleteList(List<PK> list) {
		int rows = 0;
		try {
			return getSqlSession().delete(Xmlnamespace+"."+SQLID_DELETE_PARAM, list);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rows;
	}
	public List<T> selectParam(Map<Key, Val> param) {
		try {
			return getSqlSession().selectList(Xmlnamespace+"."+SQLID_SELECT_PARAM, param);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public PagingResult<T> selectPagination(PageEntity pageentity) {
		try {  
            int page = pageentity.getPage() == null || "".equals(pageentity.getPage()) ? 1 : pageentity.getPage(); //默认为第一页  
            int size = pageentity.getSize() == null || "".equals(pageentity.getSize()) ? 15 : pageentity.getSize();; //默认每页15个  
              
            RowBounds rowBounds = new RowBounds((page-1)*size, size);  
              
			Map param = pageentity.getParams();  
            if (param != null) {  
                param.put("orderColumn", pageentity.getOrderColumn());  
                param.put("orderTurn", pageentity.getOrderTurn());  
            }else {  
                param = new HashMap();  
                param.put("orderColumn", pageentity.getOrderColumn());  
                param.put("orderTurn", pageentity.getOrderTurn());  
            }  
              
            List<T> resultList = getSqlSession().selectList(Xmlnamespace + "." + SQLID_SELECT_PARAM,param,rowBounds);  
            int totalSize = countParam(pageentity.getParams());  
              
            PagingResult<T> pagingResult = new PagingResult<T>();  
            pagingResult.setCurrentPage(page);  
            pagingResult.setTotalSize(totalSize);  
            pagingResult.setResultList(resultList);  
            return pagingResult;  
              
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
	}
	public int count() {
		int rows =0;
		try {
			rows = getSqlSession().selectOne(Xmlnamespace+"."+SQLID_COUNT);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rows;
	}
	public int countParam(Object param) {
		int rows = 0;
		try {
			rows = getSqlSession().selectOne(Xmlnamespace+"."+SQLID_COUNT_PARAM, param);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rows;
	}
	public int truncate() {
		int rows =0;
		try {
			rows = getSqlSession().delete(Xmlnamespace+"."+SQLID_TRUNCATE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rows;
	}
	@Override
	public T selectOne(Object param) {
		printLog(SQLID.SQLID_SELECT_ONE.toString(),param.toString());
		this.getNampSpace();
		return getSqlSession().selectOne(this.Xmlnamespace+"."+SQLID.SQLID_SELECT_ONE, param);
	}
	/** 
     * 日志打印 
     * @param sqlId 
     * @param param 
     */  
    public void printLog(String sqlId,Object param){  
        Configuration configuration = getSqlSession().getConfiguration();  
        //sqlId为配置文件中的sqlid  
        MappedStatement mappedStatement = configuration.getMappedStatement(sqlId);  
        //param为传入到sql语句中的参数  
        BoundSql boundSql = mappedStatement.getBoundSql(param);  
        //得到sql语句  
        String sql = boundSql.getSql().trim();  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        log.info("info-sql: "+sdf.format(new Date())+"  "+sql);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public String getNampSpace() {  
        Class<T> clazz = (Class)GenericsUtils.getSuperClassGenricType(this.getClass());  
        String simpleName = clazz.getSimpleName() + "Mapper";  
        return simpleName;  
    }
}
